<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>

    // instanceof的判断：
    // 1. 任何对象和方法都是Object的实例
    // 2. 任何方法都是Function的实例
    // 3. new的对象是当前构造函数的实例
      

    // 首先，原型链的机制实际上就是已经实现了上面的判断
    // 任何对象obj会走：
    // 1. obj.__proto__ => constructor.prototype
    // 2. obj.__proto__.__proto__ => constructor.prototype.__proto__ => Object.prototype
    // 3. obj.__proto__.__proto__.__proto__ =>  Object.prototype.__proto__ => null
    // 任何fuction包括(constructor)都会走：
    // 1. function.__proto__ => Function(就是function的construction).prototype
    // 2. function.__proto__.__proto__ => Function.prototype.__proto__ => Object.prototype
    // 3. function.__proto__.__proto__.__proto__ => Object.prototype.__proto__ => null

    // 简化：
    // 对象实例一定是当前构造函数和Object的实例
    // 1. obj.__proto__ => constructor.prototype
    // 2. obj.__proto__.__proto__ => Object.prototype
    // 3. obj.__proto__.__proto__.__proto__ => null

    // 方法实例一定是Function(构造函数)和Object的实例
    // 1. function.__proto__ => Function(construction).prototype
    // 2. function.__proto__.__proto__ => Object.prototype
    // 3. function.__proto__.__proto__.__proto__ => null

    // 此时原型链的机制就判断了实例和构造函数的关系，只要递归的求 .__proto__ 来判断传入的构造函数的原型是否匹配
    // 如果匹配那这个传入对象(方法也是对象)就是传入的构造方法的实例

    // 具体实现如下：

    function _instanceOf(instance, constructor) {
      // 如果递归达到原型链的顶端，直接返回false
      if (instance === null)
        return false
        // getPrototypeOf是Object的静态方法，得到隐式原型
      if (Object.getPrototypeOf(instance) === constructor.prototype)
        return true
      else
       // 递归 .__proto__判斷
        return _instanceOf(Object.getPrototypeOf(instance), constructor)
    }

    function fqm() { }
    var a = new fqm()
    console.log(_instanceOf(a, fqm))
    console.log(_instanceOf(a, Object))
    console.log(_instanceOf(a, Function))
    console.log(_instanceOf(Object, Function))
    console.log(_instanceOf(Function, Object))
  </script>
</body>

</html>